package com.fessc.develop.utils;

import com.fessc.develop.model.enums.EnumDataType;
import org.apache.commons.lang3.StringUtils;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Random;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

public class BusiUtil {

    /**
     * 对象是否为空
     *
     * @param obj Object
     * @return boolean
     */
    public static boolean isNull(Object obj) {
        return isNullObj(obj);
    }

    /**
     * 对象是否不为空
     *
     * @param obj Object
     * @return boolean
     */
    public static boolean isNotNull(Object obj) {
        return !isNull(obj);
    }

    /**
     * 判断对象是否为Null，数组size = 0,字符串 length = 0
     *
     * @param obj Object
     * @return boolean
     */
    private static boolean isNullObj(Object obj) {
        if (obj == null) {
            return true;
        }
        if (obj instanceof String) {
            return StringUtils.isEmpty((String) obj);
        } else if (obj instanceof List) {
            return ((List<?>) obj).isEmpty();
        } else {
            return obj == null;
        }
    }

    /**
     * 字符类型比较是否相等
     *
     * @param s
     * @param t
     * @return
     */
    public static boolean isEquals(String s, String t) {
        return StringUtils.equals(s, t);
    }

    /**
     * 字符类型比较是否不等
     *
     * @param s
     * @param t
     * @return
     */
    public static boolean isNotEquals(String s, String t) {
        return !isEquals(s, t);
    }

    /**
     * 对象是否全部不为null
     *
     * @param objs
     * @return
     */
    public static boolean isNotNullAll(Object... objs) {
        for (int i = 0; i < objs.length; i++) {
            if (isNull(objs[i])) {
                return false;
            }
        }
        return true;
    }

    /**
     * 字符串空值替换
     *
     * @param sourceExp
     * @param targetExp
     * @return string
     */
    public static String nvl(String sourceExp, String targetExp) {
        if (isNull(sourceExp)) {
            return targetExp;
        } else {
            return sourceExp;
        }
    }

    /**
     * 获取随机数
     *
     * @param len
     * @return string
     */
    public static String getRandomNumber(String key, int len) {
        Random random = new Random();
        StringBuilder stringBuilder = new StringBuilder();
        String keyString = BusiUtil.isNull(key) ? "abcdefghijklmnopqrstuvwxyz0123456789" : key;
        for (int i = 0; i < len; ++i) {
            stringBuilder.append(keyString.charAt(random.nextInt(keyString.length())));
        }
        return stringBuilder.toString();
    }

    /**
     * 获取流水号
     * 格式：日期（yyyyMMddHHmmss）+随机数
     *
     * @param prefix
     * @param len
     * @return string
     */
    public static String getSerialNumber(String prefix, String key, int len) {
        return prefix + DateUtil.getCurrentDateTime(DateUtil.CURRENT_TIMESTAMP) + BusiUtil.getRandomNumber(key, len);
    }

    /**
     * 获取日志流水号随机数
     *
     * @param prefix
     * @param len
     * @return string
     */
    public static String getMDCLogId(String prefix, int len) {
        Random random = new Random();
        StringBuilder stringBuilder = new StringBuilder();
        String keyString = "abcdefghijklmnopqrstuvwxyz0123456789";
        for (int i = 0; i < len; ++i) {
            stringBuilder.append(keyString.charAt(random.nextInt(keyString.length())));
        }
        return prefix + stringBuilder.toString();
    }

    /**
     * 数据字典替换
     *
     * @param sourceString
     * @return string
     */
    public static String getEnumSubString(String sourceString) {
        String returnValue = sourceString;
        for (EnumDataType dataType : EnumDataType.values()) {
            if (BusiUtil.isNotNull(sourceString) && sourceString.contains(dataType.getDateCode())) {
                returnValue = dataType.getDateCode();
                break;
            }
        }
        return returnValue;
    }

    /**
     * 根据ID获取枚举的名称
     *
     * @param enumId
     * @param type
     * @return string
     */
    public static String getEnumDataName(String enumId, String type) {
        String returnValue = enumId;
        for (EnumDataType dataType : EnumDataType.values()) {
            if (BusiUtil.isNotNull(enumId) && dataType.getDateCode().equals(enumId) && dataType.name().contains(type)) {
                returnValue = dataType.name().substring(dataType.name().indexOf("_") + 1);
                break;
            }
        }
        return returnValue;
    }

    /**
     * 根据ID获取枚举值
     *
     * @param enumId
     * @param type
     * @return string
     */
    public static String getEnumDatavalue(String enumId, String type) {
        String returnValue = enumId;
        for (EnumDataType dataType : EnumDataType.values()) {
            if (BusiUtil.isNotNull(enumId) && (type + "_"+enumId).equals(dataType.name())) {
                returnValue = dataType.getDateCode();
                break;
            }
        }
        return returnValue;
    }

    /**
     * 文件类型
     *
     * @param fileFormat
     * @return string
     */
    public static String getFileFormat(String fileFormat) {
        String returnValue = "";
        switch (fileFormat) {
            case "JPG":
                returnValue = "01";
                break;
            case "JPEG":
                returnValue = "02";
                break;
            case "PNG":
                returnValue = "03";
                break;
            case "TXT":
                returnValue = "04";
                break;
            case "XLSX":
                returnValue = "05";
                break;
            case "XLS":
                returnValue = "06";
                break;
            case "PDF":
                returnValue = "07";
                break;
            case "RAR":
                returnValue = "08";
                break;
            case "ZIP":
                returnValue = "09";
                break;
            default:
                returnValue = "";
        }
        return returnValue;
    }

    /**
     * 解压缩
     */
    public static byte[] unzip(byte[] source) throws Exception {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        ByteArrayInputStream in = new ByteArrayInputStream(source);
        // JDK提供的。 专门用于压缩使用的流对象。可以处理字节数组数据。
        GZIPInputStream zipIn = new GZIPInputStream(in);
        byte[] temp = new byte[256];
        int length = 0;
        while ((length = zipIn.read(temp, 0, temp.length)) != -1) {
            out.write(temp, 0, length);
        }
        // 将字节数组输出流中的数据，转换为一个字节数组。
        byte[] target = out.toByteArray();
        zipIn.close();
        out.close();
        return target;
    }

    /**
     * 压缩
     *
     * @param source 源数据，需要压缩的数据
     * @return 压缩后的数据。
     * @throws Exception
     */
    public static byte[] zip(byte[] source) throws Exception {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        // 输出流，JDK提供的，提供解压缩功能。
        GZIPOutputStream zipOut = new GZIPOutputStream(out);
        // 将压缩信息写入到内存。 写入的过程会实现解压。
        zipOut.write(source);
        // 结束
        zipOut.finish();
        byte[] target = out.toByteArray();
        zipOut.close();
        return target;
    }

    public static String subFoolString(String str, int length) {
        try {
            if (BusiUtil.isNull(str)) {
                return str;
            }
            if (str.getBytes(StandardCharsets.UTF_8).length <= length) {
                return str;
            }
            int idx = 0;
            for (int i = 0; i < str.length(); i++) {
                String s = str.substring(i, i + 1);
                byte[] b = s.getBytes(StandardCharsets.UTF_8);
                if (idx + b.length > length) {
                    break;
                }
            }
            byte[] bytes = new byte[idx];
            byte[] ts = str.getBytes(StandardCharsets.UTF_8);
            System.arraycopy(ts, 0, bytes, 0, idx);
            return new String(bytes, StandardCharsets.UTF_8);
        } catch (Exception ex) {
            return str;
        }
    }

}
